<?php
/**
 * User：liujun
 * Date：2022/3/13
 * Time：4:54 PM
 */

namespace Encore\Admin\Auth\Database;

use Cache;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;

/**
 * Class ChinaArea.
 * @property int $id
 * @property int $parent_id
 * @property string $name
 * @property string $code
 * @property string $created_at
 * @property string $updated_at
 */
class ChinaArea extends Model
{
    /**
     * 所有城市
     * @return mixed
     */
    public static function allData()
    {
        return Cache::remember('china_areas', now()->addMonth(), function () {
            return static::with('children.children')->where('parent_id', 1)->get();
        });
    }

    public static function parentOptions(): Collection
    {
        return static::pluck('name', 'id');
    }

    /**
     * 父级
     * @return BelongsTo
     */
    public function parent(): BelongsTo
    {
        return $this->belongsTo(static::class, 'parent_id');
    }

    /**
     * 子级
     * @return HasMany
     */
    public function children(): HasMany
    {
        return $this->hasMany(static::class, 'parent_id');
    }

    /**
     * 获取省市区
     * @param $p
     * @param $c
     * @param $d
     * @return null[]
     */
    public static function getPcd($p, $c, $d): array
    {
        $array = static::query()->whereIn('code', [$p, $c, $d])->pluck('name', 'code')->toArray();
        return [
            $array[$p] ?? null,
            $array[$c] ?? null,
            $array[$d] ?? null,
        ];
    }

    /**
     * get province city district code through province city district name
     * @param ...$names
     * @return array
     */
    public static function getCodesByNames(...$names): array
    {
        return static::query()->whereIn('name', $names)
            ->get(['code'])
            ->map(fn($item) => [
                'code'   => $item->code,
                'prefix' => substr($item->code, 0, 2),
            ])
            ->groupBy('prefix')
            ->firstOrFail(fn($item) => $item->count() === 3)
            ->sortBy('code')
            ->pluck('code')
            ->toArray();
    }
}